from __future__ import annotations

import shlex
import subprocess
from datetime import datetime, timezone
from pathlib import Path
from typing import Optional

from .accounts import load_accounts
from .events import append_event, read_owner_events
from .paths import get_memory_dir


def _parse_iso(s: str) -> datetime:
    try:
        # Expect 'Z' suffix
        if s.endswith("Z"):
            s = s[:-1] + "+00:00"
        return datetime.fromisoformat(s)
    except Exception:
        return datetime.now(timezone.utc)


def _last_post_time(owner: str, actor: str) -> Optional[datetime]:
    events = read_owner_events(get_memory_dir(), owner, actors=[actor])
    posts = [e for e in events if e.type == "post"]
    if not posts:
        return None
    posts.sort(key=lambda e: e.created_at, reverse=True)
    return _parse_iso(posts[0].created_at)


def _message_from_cmd(cmd: str) -> str:
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
    out, err = p.communicate(timeout=60)
    if p.returncode != 0:
        return f"auto-post command failed ({p.returncode}): {err.strip() or out.strip()}"
    return out.strip()


def run_autopost(args) -> None:
    store = load_accounts()
    owner = args.owner or store.default_owner
    actor = args.actor or store.default_actor

    last = _last_post_time(owner, actor)
    now = datetime.now(timezone.utc)
    if last is not None:
        delta = (now - last).total_seconds()
        if delta < args.if_idle:
            # Silent no-op for cron
            return

    message = args.message or ""
    if args.from_cmd:
        message = _message_from_cmd(args.from_cmd)
    if not message:
        return

    append_event(get_memory_dir(), owner, actor, "post", message, headers={"auto": "true"})
    print("auto-posted")

